﻿%{
	#include <stdio.h>
	#include <math.h>
	#include "string.h"

	#define YYERROR_VERBOSE

	int tec_shirina = 0;
	int tec_vysota = 0;
	int tec_base_point_x = 0; 
	int tec_base_point_y = 0;
	int protaj_point_x[200];
	int protaj_point_y[200];
	int last = 0;
	
	int count_of_go = 0;
	int count_of_zones = 0;
	int nazv_ind = 0;
	
	char zones_names[5][10][20];
	
	int flag_zagolovka = 1;
	int flag_protajannogo_tipa = 0;
	int flag_tochechnogo_tipa = 0;
	int flag_zony = 0;
	int flag_stop_nazv = 0;

	struct go_name
	{
	    char go_padej[3];
		char go_landshaft[30];
		char** go_nazvanie;
	};
	struct padej_forma
	{
		char padej[3];
		char ipforma[30];
	};
	struct sdvig
	{
		int storona;
		int chastichnost;
		int rasstoyanie;
	};
	
	struct go
	{
		char go_landshaft[30];
		char go_nazvanie[10][20]; 
		int shirina;
		int vysota;
		int base_point_x;
		int base_point_y;
		int key_points_x[16];
		int key_points_y[16];
		int prot_point_x[200];
		int prot_point_y[200];
		int index_last;
		int count_of_zones;
		char zone_names[5][10][20]; /* 5 зон 10 слов 30 символов*/
		struct go *nx;
	};
	
	void add(struct go** , char* , char** , int , int , int , int , int*, int*, int, char [5][10][20]);
	void calculate_keypoints(int shirina, int vysota, int base_x, int base_y,int* points_x,int* points_y);
	void opredelenie_storony(struct sdvig* sdvig_struct,char * tec_storona);
	void addressing_function(struct sdvig* sdvig_struct,int ch,int rast,char * stor);
	int find_function(struct go_name* rassm_object);
	void chastichnost_function(int storona,int *result_x,int *result_y,int index);
	void sdvig_function(int storona,int *result_x,int *result_y,int base_x,int base_y,int rasstoyanie);
	struct go_name* go_nazvanie_function(struct go_name* result, struct padej_forma* base1, char ** base2);
	void razmer_function(char * predlog,int chislo,int control);
	void mesto_function(struct go_name* obj, struct sdvig* sdv);
	void protajeniye_function1(char* glagol,char* predlog,struct go_name* obj,struct sdvig* sdv);
	void protajeniye_function2(char* glagol,struct sdvig* sdv,struct go_name* obj);
	void protajeniye_function3(char* glagol,struct sdvig* sdv);
	
	struct go* element(struct go **h,int index);
	struct go* gos;
%}
%union
{
    int IntVal;
    char* CharPointer;
    char** CharDoublePointer;
    struct padej_forma* Padej_Forma;
    struct go_name* Go_Name_Struct;
    struct sdvig* Sdvig_Struct;
}
%token SLASH SLASH2 ZAP TOCHKA DEFIS
%token <CharPointer> ZAG_SLOVO SLOVO GLAGOL_RASPOLOJENIYA ZAG_GLAGOL_RASPOLOJENIYA GLAGOL_PROTAJENIYA ZAG_GLAGOL_PROTAJENIYA  GLAGOL_RAZMEROV ZAG_GLAGOL_RAZMEROV 
%token <Padej_Forma> LANDSHAFT_1 LANDSHAFT_2 LANDSHAFT_3 CHAST_3
%token <Padej_Forma> NAPRAVLENIE_S NAPRAVLENIE_PRIL NAPRAVLENIE_SRAVN 
%token <CharPointer> CHISLO EDINICA_DLINY  SHIRINA VYSOTA ZAG_SHIRINA ZAG_VYSOTA ZONA
%token <CharPointer> PREDLOG_RP PREDLOG_DP PREDLOG_VP PREDLOG_TP PREDLOG_PP 

%type <CharDoublePointer> nazvanie
%type <IntVal> chislo 
%type <CharPointer> predlog 
%type <CharPointer> glagol_protajeniya zag_glagol_protajeniya
%type <Go_Name_Struct> go_nazvanie 
%type <Padej_Forma> landshaft 
%type <Sdvig_Struct> adres adres2 adres3
%type <Padej_Forma> napravlenie_s napravlenie_sravn napravlenie_pril chast

%% 
mir:/* пусто */
	| geographic_block		   
	{
		int i,j = 0,k;
		printf("\nBEGIN\n");
		// вывод информации по всем блокам в файл
		for(i = 0; i < count_of_go; i++)
		{
			printf("%s\n",element(&gos,i)->go_landshaft);
			for(j = 0; strcmp(element(&gos,i)->go_nazvanie[j],""); j++)
			{
				printf("%s",element(&gos,i)->go_nazvanie[j]);
				if(strcmp(element(&gos,i)->go_nazvanie[j+1],""))
				{
					printf(" ",element(&gos,i)->go_nazvanie[j]);
				}
			}
			printf("\n");
			printf("%d\n",element(&gos,i)->shirina);
			printf("%d\n",element(&gos,i)->vysota);
			printf("%d\n",element(&gos,i)->base_point_x);
			printf("%d\n",element(&gos,i)->base_point_y);
			printf("%d\n",element(&gos,i)->index_last);
			for(j = 0;j<=element(&gos,i)->index_last;j++)
			{
				if(j==element(&gos,i)->index_last)
					printf("%d::%d",element(&gos,i)->prot_point_x[j],element(&gos,i)->prot_point_y[j]);
				else
					printf("%d::%d\n",element(&gos,i)->prot_point_x[j],element(&gos,i)->prot_point_y[j]);
			}
			printf("\n");
			printf("%d\n",element(&gos,i)->count_of_zones);
			for(j = 0; j < element(&gos,i)->count_of_zones;j++)
			{
				for(k = 0; strcmp(element(&gos,i)->zone_names[j][k],""); k++)
				{
					printf("%s",element(&gos,i)->zone_names[j][k]);
					if(strcmp(element(&gos,i)->zone_names[j][k+1],"")) 
					{
						printf(" ");
					}
				}
				printf("\n");
			}
		}
		printf("END\n");
		//exit(1);
		//return 0;
	}
;

//накопление структур geographical_object
geographic_block: geographical_object 
				  |geographic_block geographical_object 
;

// инициализация структуры geographical_object                
geographical_object: 
SLASH go_nazvanie SLASH text
{  
	int i;
	if(!strcmp($2->go_landshaft,"мир"))
	{
		tec_base_point_x = tec_shirina/2;
		tec_base_point_y = tec_vysota/2;
	}
	if(!strcmp($2->go_landshaft,"скалы")||!strcmp($2->go_landshaft,"горы")||!strcmp($2->go_landshaft,"река")||!strcmp($2->go_landshaft,"дорога")) // собственные алгоритмы нахождения ширины и высоты для этих объектов
	{
		tec_shirina = ret_max(protaj_point_x,last+1)-ret_min(protaj_point_x,last+1);
		tec_vysota = ret_max(protaj_point_y,last+1)-ret_min(protaj_point_y,last+1);
		tec_base_point_x = ret_min(protaj_point_x,last+1) + tec_shirina/2;
		tec_base_point_y = ret_min(protaj_point_y,last+1) + tec_vysota/2;
	}
	add(&gos,$2->go_landshaft,$2->go_nazvanie,tec_shirina,tec_vysota,tec_base_point_x,tec_base_point_y,protaj_point_x,protaj_point_y,count_of_zones,zones_names);

	count_of_go++;	
	flag_zagolovka = 1;	
	for(i = 0; i <= last; i++)
	{
		protaj_point_x[i] = 0;
		protaj_point_y[i] = 0;
	}
	last = 0;	
	count_of_zones = 0;	
}
;
landshaft:
LANDSHAFT_1 
{
	$$ = (struct padej_forma*)malloc(sizeof(struct padej_forma)); 
	strcpy($$->padej,$1->padej);
	strcpy($$->ipforma,$1->ipforma);
}
|LANDSHAFT_2
{	
	$$ = (struct padej_forma*)malloc(sizeof(struct padej_forma)); 
	strcpy($$->padej,$1->padej);
	strcpy($$->ipforma,$1->ipforma);				
}	
|LANDSHAFT_3
{	
	$$ = (struct padej_forma*)malloc(sizeof(struct padej_forma)); 
	strcpy($$->padej,$1->padej);
	strcpy($$->ipforma,$1->ipforma);				
}
;
nazvanie: 
ZAG_SLOVO 
{ 
	int i;
	nazv_ind = 0;
	$$ = (char**)malloc(10*sizeof(char*));
	for(i = 0; i < 10; i++)
	{
		$$[i] = (char*)malloc(20*sizeof(char));	
		strcpy($$[i],"");
	}	
	strcpy($$[0],$1);
	
}
|nazvanie ZAG_SLOVO //для составных названий
{
	nazv_ind++;
	strcpy($1[nazv_ind],$2);
	$$ = $1;
}
|nazvanie DEFIS ZAG_SLOVO
{
	strcat($1[nazv_ind],"-");
	strcat($1[nazv_ind],$3);
	$$ = $1;
}
;
go_nazvanie:  
landshaft nazvanie 
{     
	$$ = go_nazvanie_function($$,$1,$2);		   
}   					       
|nazvanie landshaft 
{
	$$ =  go_nazvanie_function($$,$2,$1);
}
;
zone: SLASH2 zona nazvanie SLASH2
{ 
	int i;
	if(flag_tochechnogo_tipa == 1)
	{
		flag_zony = 1;		
		for(i = 0; strcmp($3[i],""); i++)
		{
			strcpy(zones_names[count_of_zones][i],$3[i]);
		}
		count_of_zones++;
	}
}
;
// описательный блок географического? объекта или любого
text:   /* пусто */
		|predlogenie 
		|text predlogenie 
;
predlogenie: zag_slovo slova constructions slova tochka 
			 |zag_constructions slova tochka
			 |zone
			 //|error /*как-то сообщить о начале предложения с маленькой буквы?*/
;
constructions: construction /*не пустое так как у construction есть обработчик error*/
			   |constructions slova zap slova construction
			   //|error //!
;
construction:   mesto 
				|razmer 
				|protajeniye 
				|error /*конструкция может быть не достроена или постоена неправильно*/
;
zag_constructions: zag_construction
				  |zag_constructions slova zap slova constructions
				  //|error //!
;				  
zag_construction: zag_mesto 
				  |zag_razmer 
				  |zag_protajeniye
				  |error /*конструкция может быть не достроена или постоена неправильно*/
;
zag_slovo: ZAG_SLOVO 
;
predlog: PREDLOG_RP {$$ = (char*)malloc(6*sizeof(char)); strcpy($$,$1);}
		|PREDLOG_DP {$$ = (char*)malloc(6*sizeof(char)); strcpy($$,$1);}
		|PREDLOG_VP {$$ = (char*)malloc(6*sizeof(char)); strcpy($$,$1);} 
		|PREDLOG_TP {$$ = (char*)malloc(6*sizeof(char)); strcpy($$,$1);}
		|PREDLOG_PP {$$ = (char*)malloc(6*sizeof(char)); strcpy($$,$1);}
;
slova:  /* пусто */
		|SLOVO 
		|slova SLOVO 
;
tochka: TOCHKA 
;
zap: ZAP 
;
chast: 	CHAST_3 /*добавить часть1 часть2 район регион*/	
		{
			$$ = (struct padej_forma*)malloc(sizeof(struct padej_forma)); 
			strcpy($$->padej,$1->padej);
			strcpy($$->ipforma,$1->ipforma);
		}
;
adres: predlog slova napravlenie_pril slova chast
	   {/* в северной части */	
			if(!strcmp($1,"в")&&!strcmp($3->padej,"PP")&&!strcmp($5->padej,"PP"))
			{
			    $$ = (struct sdvig*)malloc(sizeof(struct sdvig)); // конструкция собрана верно
				addressing_function($$,1,0,$3->ipforma);
			}
			else
				$$ = NULL; // конструкция собрана неверно
	   }
	   |predlog slova chislo slova edinica_dliny slova predlog slova napravlenie_s slova predlog
	   {/* в 100 км к северу от */
			if(!strcmp($1,"в")&&!strcmp($7,"к")&&!strcmp($11,"от")&&!strcmp($9->padej,"DP"))
			{	
				$$ = (struct sdvig*)malloc(sizeof(struct sdvig)); // конструкция собрана верно												
				addressing_function($$,0,$3,$9->ipforma);
			}	
			else
				$$ = NULL;
	   }
       |predlog slova chislo slova edinica_dliny slova napravlenie_sravn 
       {/* на 100 км севернее */
			if(!strcmp($1,"на")&&!strcmp($7->padej,"IP"))
			{
				$$ = (struct sdvig*)malloc(sizeof(struct sdvig)); // конструкция собрана верно
				addressing_function($$,0,$3,$7->ipforma);
			}
			else
				$$ = NULL; // конструкция собрана неверно
       }
;
mesto: glagol_raspolojeniya slova adres slova go_nazvanie
{
	mesto_function($5,$3);
}
;
zag_mesto: zag_glagol_raspolojeniya slova adres slova go_nazvanie
{
	mesto_function($5,$3);
}
;

protajeniye: glagol_protajeniya slova predlog slova go_nazvanie slova adres2
{ /* главная конструкция протяжения(задаёт начальную точку и первое смещение) - течёт,тянутся,ведёт от объекта на юг на 200 км */
  
	protajeniye_function1($1,$3,$5,$7);
}
|glagol_protajeniya slova adres3 slova go_nazvanie
{ /* главная конструкция протяжения(задаёт начальную точку) - течёт,тянутся,ведёт по части объекта */

	protajeniye_function2($1,$3,$5);	
}
|glagol_protajeniya slova adres2
{ /* второсепенная конструкция протяжения - течёт,тянутся,ведёт на юг на 200 км */
	protajeniye_function3($1,$3);
	
}
;
zag_protajeniye: zag_glagol_protajeniya slova predlog slova go_nazvanie slova adres2
{ /* главная конструкция протяжения(задаёт начальную точку и первое смещение) - течёт,тянутся,ведёт от объекта на юг на 200 км */
  
	protajeniye_function1($1,$3,$5,$7);
}
|zag_glagol_protajeniya slova adres3 slova go_nazvanie
{
	protajeniye_function2($1,$3,$5);
}
|zag_glagol_protajeniya slova adres2
{
	protajeniye_function3($1,$3);
}
;
adres2: predlog slova napravlenie_s slova predlog slova chislo slova edinica_dliny
{ /*  на юг на 200 км */
	if(!strcmp($1,"на")&&!strcmp($5,"на")&&!strcmp($3->padej,"VP"))
	{
		$$ = (struct sdvig*)malloc(sizeof(struct sdvig)); // конструкция собрана верно
		addressing_function($$,0,$7,$3->ipforma);
	}
	else
		$$ = NULL;
}
;
adres3: predlog slova napravlenie_pril slova chast
{ /* по восточной части */
	if(!strcmp($1,"по")&&!strcmp($3->padej,"DP")&&!strcmp($5->padej,"DP"))
	{
		$$ = (struct sdvig*)malloc(sizeof(struct sdvig)); // конструкция собрана верно
		addressing_function($$,1,0,$3->ipforma);
	}
	else
		$$ = NULL;
}
;
zona: ZONA 
;			
shirina: SHIRINA 
;
vysota: VYSOTA 
;
zag_shirina: ZAG_SHIRINA 
;
zag_vysota: ZAG_VYSOTA 
;
glagol_protajeniya: GLAGOL_PROTAJENIYA 
				{
					$$ = (char*)malloc(30*sizeof(char)); 
					strcpy($$,$1);
				}
;
glagol_razmerov: GLAGOL_RAZMEROV  
;
glagol_raspolojeniya: GLAGOL_RASPOLOJENIYA 
;

zag_glagol_protajeniya: ZAG_GLAGOL_PROTAJENIYA 
				{
					$$ = (char*)malloc(30*sizeof(char)); 
					strcpy($$,$1);
				}
;
zag_glagol_razmerov: ZAG_GLAGOL_RAZMEROV  
;
zag_glagol_raspolojeniya: ZAG_GLAGOL_RASPOLOJENIYA  
;

chislo: CHISLO { $$ = atoi($1); }
;
edinica_dliny: EDINICA_DLINY 
;
napravlenie_s: NAPRAVLENIE_S 
				{
					$$ = (struct padej_forma*)malloc(sizeof(struct padej_forma));
					strcpy($$->padej,$1->padej);
					strcpy($$->ipforma,$1->ipforma);
				}
;
napravlenie_pril: NAPRAVLENIE_PRIL
				{
					$$ = (struct padej_forma*)malloc(sizeof(struct padej_forma));
					strcpy($$->padej,$1->padej);
					strcpy($$->ipforma,$1->ipforma);
				}
;
napravlenie_sravn: NAPRAVLENIE_SRAVN 
				{
					$$ = (struct padej_forma*)malloc(sizeof(struct padej_forma)); 
					strcpy($$->padej,$1->padej);
					strcpy($$->ipforma,$1->ipforma);
				}
;
razmer: shirina slova glagol_razmerov slova predlog slova chislo slova edinica_dliny
		{
			razmer_function($5,$7,1);
		}
		|vysota slova glagol_razmerov slova predlog	slova chislo slova edinica_dliny
		{
			razmer_function($5,$7,0);
		}
		|glagol_razmerov slova shirina slova predlog slova chislo slova edinica_dliny
		{	
			razmer_function($5,$7,1);	
		}
		|glagol_razmerov slova vysota slova predlog slova chislo slova edinica_dliny
		{
			razmer_function($5,$7,0);
		}		
;
zag_razmer:	zag_shirina slova glagol_razmerov slova predlog slova chislo slova edinica_dliny
		{
			razmer_function($5,$7,1);
		}
		|zag_vysota slova glagol_razmerov slova predlog	slova chislo slova edinica_dliny
		{
			razmer_function($5,$7,0);
		}
		|zag_glagol_razmerov slova shirina slova predlog slova chislo slova edinica_dliny
		{	
			razmer_function($5,$7,1);	
		}
		|zag_glagol_razmerov slova vysota slova predlog slova chislo slova edinica_dliny
		{
			razmer_function($5,$7,0);
		}
;
%%
int
yyerror(const char *s)  
{
    //printf ("%s\n", s);
}
void 
chastichnost_function(int storona,int *result_x,int *result_y,int index) 
{
	if(storona == 1) // северо-западная часть
	{
		*result_x = element(&gos,index)->key_points_x[0]+(element(&gos,index)->key_points_x[1]-element(&gos,index)->key_points_x[0])/2; 
		*result_y = element(&gos,index)->key_points_y[0]+(element(&gos,index)->key_points_y[4]-element(&gos,index)->key_points_y[0])/2;
	}
	if(storona == 2) // северная часть
	{
		*result_x = element(&gos,index)->key_points_x[1]+(element(&gos,index)->key_points_x[2]-element(&gos,index)->key_points_x[1])/2; 
		*result_y = element(&gos,index)->key_points_y[1]+(element(&gos,index)->key_points_y[5]-element(&gos,index)->key_points_y[1])/2;
	}
	if(storona == 3) // северо-восточная часть
	{
		*result_x = element(&gos,index)->key_points_x[2]+(element(&gos,index)->key_points_x[3]-element(&gos,index)->key_points_x[2])/2; 
		*result_y = element(&gos,index)->key_points_y[2]+(element(&gos,index)->key_points_y[6]-element(&gos,index)->key_points_y[2])/2;
	}
	if(storona == 4) // западная часть
	{
		*result_x = element(&gos,index)->key_points_x[4]+(element(&gos,index)->key_points_x[5]-element(&gos,index)->key_points_x[4])/2;
		*result_y = element(&gos,index)->key_points_y[4]+(element(&gos,index)->key_points_y[8]-element(&gos,index)->key_points_y[4])/2;
	}
	if(storona == 5) // центральная часть
	{
		*result_x = element(&gos,index)->key_points_x[5]+(element(&gos,index)->key_points_x[6]-element(&gos,index)->key_points_x[5])/2;
		*result_y = element(&gos,index)->key_points_y[5]+(element(&gos,index)->key_points_y[9]-element(&gos,index)->key_points_y[5])/2;
	}
	if(storona == 6) // восточная часть
	{
		*result_x = element(&gos,index)->key_points_x[6]+(element(&gos,index)->key_points_x[7]-element(&gos,index)->key_points_x[6])/2;
		*result_y = element(&gos,index)->key_points_y[6]+(element(&gos,index)->key_points_y[10]-element(&gos,index)->key_points_y[6])/2;
	}
	if(storona == 7) // юго-западная часть
	{
		*result_x = element(&gos,index)->key_points_x[8]+(element(&gos,index)->key_points_x[9]-element(&gos,index)->key_points_x[8])/2;
		*result_y = element(&gos,index)->key_points_y[8]+(element(&gos,index)->key_points_y[12]-element(&gos,index)->key_points_y[8])/2;
	}
	if(storona == 8) // южная часть
	{
		*result_x = element(&gos,index)->key_points_x[9]+(element(&gos,index)->key_points_x[10]-element(&gos,index)->key_points_x[9])/2; 
		*result_y = element(&gos,index)->key_points_y[9]+(element(&gos,index)->key_points_y[13]-element(&gos,index)->key_points_y[9])/2;
	}
	if(storona == 9) // юго-восточеая часть
	{
		*result_x = element(&gos,index)->key_points_x[10]+(element(&gos,index)->key_points_x[11]-element(&gos,index)->key_points_x[10])/2; 
		*result_y = element(&gos,index)->key_points_y[10]+(element(&gos,index)->key_points_y[14]-element(&gos,index)->key_points_y[10])/2;
	}
}
void
sdvig_function(int storona,int *result_x,int *result_y,int base_x,int base_y,int rasstoyanie)
{
	if(storona == 1) // смещение на северо-запад
	{
		*result_x = base_x - rasstoyanie/sqrt(2) ; 
		*result_y = base_y - rasstoyanie/sqrt(2) ;
	}
	if(storona == 2) // смещение на север
	{				
		*result_x = base_x;
		*result_y = base_y - rasstoyanie ;
	}
	if(storona == 3) // смещение на северо-восток
	{
		*result_x = base_x + rasstoyanie/sqrt(2) ;
		*result_y = base_y - rasstoyanie/sqrt(2) ;
	}
	if(storona == 4) // смещение на запад
	{
		*result_x = base_x - rasstoyanie ;
		*result_y = base_y;
	}
	// центральное направление не участвует
	if(storona == 6) // смещение на восток
	{
		*result_x = base_x + rasstoyanie ;
		*result_y = base_y;
	}
	if(storona == 7) // смещение на юго-запад
	{
		*result_x = base_x - rasstoyanie/sqrt(2) ; 
		*result_y = base_y + rasstoyanie/sqrt(2) ;
	}
	if(storona == 8) // смещение на юг
	{
		*result_x = base_x;
		*result_y = base_y + rasstoyanie ;
	}
	if(storona == 9) // смещение на юго-восток
	{
		*result_x = base_x + rasstoyanie/sqrt(2) ; 
		*result_y = base_y + rasstoyanie/sqrt(2) ;
	}
}
/* обработчик конструкции go_nazvanie */
struct go_name*
go_nazvanie_function(struct go_name* result, struct padej_forma* base1, char ** base2)
{
	int i;
	result = (struct go_name*)malloc(sizeof(struct go_name)); 
	result->go_nazvanie = (char**)malloc(10*sizeof(char*));
	for(i = 0; i < 10; i++)
	{
		result->go_nazvanie[i] = (char*)malloc(20*sizeof(char)); 
		strcpy(result->go_nazvanie[i],"");
	}
	if(flag_zagolovka == 0)
	{							
		strcpy(result->go_padej,base1->padej);
		strcpy(result->go_landshaft,base1->ipforma); 
		for(i = 0; strcmp(base2[i],""); i++)
		{
			strcpy(result->go_nazvanie[i],base2[i]);
		}	
	}
	if(flag_zagolovka == 1  && !strcmp(base1->padej,"IP"))
	{	
		
		tec_shirina = 0;
		tec_vysota = 0;		
		tec_base_point_x = 0;
		tec_base_point_y = 0;
		strcpy(result->go_padej,base1->padej);		
		strcpy(result->go_landshaft,base1->ipforma); 
		
		for(i = 0; strcmp(base2[i],""); i++)
		{
			strcpy(result->go_nazvanie[i],base2[i]);
		}
		flag_zagolovka = 0;
		flag_protajannogo_tipa = 0;
		flag_tochechnogo_tipa = 0;
		flag_zony = 0;
		if(!strcmp(base1->ipforma,"горы")||!strcmp(base1->ipforma,"скалы"))
		{
			flag_protajannogo_tipa = 1;
		}
		if(!strcmp(base1->ipforma,"река"))
		{	
			flag_protajannogo_tipa = 2;
		}
		if(!strcmp(base1->ipforma,"дорога"))
		{
			flag_protajannogo_tipa = 3;
		}
		if(!strcmp(base1->ipforma,"место"))
		{
			flag_tochechnogo_tipa = 1;
		}
	}
	return result;
}
/* обработчик конструкции размера */
void 
razmer_function(char * predlog,int chislo,int control)
{
	if(flag_protajannogo_tipa == 0 && flag_tochechnogo_tipa == 0) 
	{
		if(!strcmp("на",predlog))
		{
			if(control == 1)
			{
				tec_shirina = chislo;
			}
			else
			{
				tec_vysota = chislo;
			}
		}
	}
}
/* обработчик конструкции местоположения */
void 
mesto_function(struct go_name* obj, struct sdvig* sdv)
{
	int index;	 	
	if(!strcmp(obj->go_padej,"RP") && sdv != NULL && flag_protajannogo_tipa == 0 && flag_zony == 0) 
	{
		/* в списке созданных объектов есть объект относительно которого происходит адресация ?*/	
		index = find_function(obj);	
		if(index>=0) 
		{			
			if(sdv->chastichnost == 1) // отношение части и целого
			{
				chastichnost_function(sdv->storona,&tec_base_point_x,&tec_base_point_y,index);
			}
			else // отношение сдвига
			{				
				sdvig_function(sdv->storona,&tec_base_point_x,&tec_base_point_y,element(&gos,index)->base_point_x,element(&gos,index)->base_point_y,sdv->rasstoyanie);
			}
		}
    }
}
/* обработчик конструкции протяжения */
void 
protajeniye_function1(char* glagol,char* predlog,struct go_name* obj,struct sdvig* sdv)
{
	/*если глагол протяжения по смыслу согласуется с типом протяженного объекта*/
	int index;
	if((flag_protajannogo_tipa == 1 && (!strcmp(glagol,"тянутся")||(!strcmp(glagol,"Тянутся"))))||(flag_protajannogo_tipa == 2 && (!strcmp(glagol,"Течет")||!strcmp(glagol,"течет")||!strcmp(glagol,"Несет свои воды")||!strcmp(glagol,"несет свои воды")))||(flag_protajannogo_tipa == 3 && (!strcmp(glagol,"Ведет")||!strcmp(glagol,"Идет")||!strcmp(glagol,"Тянется")||!strcmp(glagol,"ведет")||!strcmp(glagol,"идет")||!strcmp(glagol,"тянется"))))
	{
		if(sdv!=NULL && sdv->chastichnost == 0 && !strcmp(obj->go_padej,"RP") && !strcmp(predlog,"от"))
		{
			index = find_function(obj);	
			if(index>=0) 
			{
				protaj_point_x[0] = element(&gos,index)->base_point_x;
				protaj_point_y[0] = element(&gos,index)->base_point_y;
				sdvig_function(sdv->storona,&protaj_point_x[last+1],&protaj_point_y[last+1],protaj_point_x[last],protaj_point_y[last],sdv->rasstoyanie);
				last++;
			}	
		}
	}
}
void 
protajeniye_function2(char* glagol,struct sdvig* sdv,struct go_name* obj)
{
	int index;
	if((flag_protajannogo_tipa == 1 && (!strcmp(glagol,"тянутся")||(!strcmp(glagol,"Тянутся"))))||(flag_protajannogo_tipa == 2 && (!strcmp(glagol,"Течет")||!strcmp(glagol,"течет")||!strcmp(glagol,"Несет свои воды")||!strcmp(glagol,"несет свои воды")))||(flag_protajannogo_tipa == 3 && (!strcmp(glagol,"Ведет")||!strcmp(glagol,"Идет")||!strcmp(glagol,"Тянется")||!strcmp(glagol,"ведет")||!strcmp(glagol,"идет")||!strcmp(glagol,"тянется"))))
	{	
		if(sdv!=NULL && sdv->chastichnost == 1 && !strcmp(obj->go_padej,"RP"))
		{
			index = find_function(obj);	
			if(index>=0) 
			{
				chastichnost_function(sdv->storona,&protaj_point_x[0],&protaj_point_y[0],index);
			}	
		}
	}
}
void 
protajeniye_function3(char* glagol,struct sdvig* sdv)
{
	if((flag_protajannogo_tipa == 1 && (!strcmp(glagol,"тянутся")||(!strcmp(glagol,"Тянутся"))))||(flag_protajannogo_tipa == 2 && (!strcmp(glagol,"Течет")||!strcmp(glagol,"течет")||!strcmp(glagol,"Несет свои воды")||!strcmp(glagol,"несет свои воды")))||(flag_protajannogo_tipa == 3 && (!strcmp(glagol,"Ведет")||!strcmp(glagol,"Идет")||!strcmp(glagol,"Тянется")||!strcmp(glagol,"ведет")||!strcmp(glagol,"идет")||!strcmp(glagol,"тянется"))))
	{	
		if(sdv!=NULL && sdv->chastichnost == 0) // отношение смещения
		{	
			sdvig_function(sdv->storona,&protaj_point_x[last+1],&protaj_point_y[last+1],protaj_point_x[last],protaj_point_y[last],sdv->rasstoyanie);
			last++;	
		}	
	}
}
/* поиск имени */					 
int 
find_function(struct go_name* rassm_object)
{
	int i,j,t,k = 0,i_max=-1,sovp_slova;
	int max[10];
	int result=0;
	for(i = 0; i <10; i++)
	{
		max[i] = 0; 
	} 
	for(i = 0; i < count_of_go; i++) // поиск наиболее близкой формы названия
	{
		if(!strcmp(rassm_object->go_landshaft,element(&gos,i)->go_landshaft)) // тип совпал
		{
			sovp_slova = 0;
			for(t = 0; strcmp(element(&gos,i)->go_nazvanie[t],""); t++)
			{
				k = 0;
				for(j = 0; j < strlen(element(&gos,i)->go_nazvanie[t]); j++)
				{
					if(element(&gos,i)->go_nazvanie[t][j] == rassm_object->go_nazvanie[t][j])
					{
						k++; // сколько символов совпало
					}
					else
					{
						break;
					}
				}
							   
				if(k >= max[t] && (strlen(rassm_object->go_nazvanie[t]) >= strlen(element(&gos,i)->go_nazvanie[t])))
				{
					max[t] = k;
					sovp_slova++; /* увеличение числа совпавших слов */
				}					
			}
			for(t = 0; strcmp(element(&gos,i)->go_nazvanie[t],""); t++){}
			if(t == sovp_slova)	
			{
				i_max = i; /* все слова совпали*/
			}
		}
	}
	return i_max;
}	
int
ret_max(int *mas,int count)
{
	int i,max = 0;
	max = mas[0];
	for(i = 1; i < count; i++)
	{
		if(mas[i]>max)
		{
			max = mas[i];
		}
	}
	return max;
}
int
ret_min(int *mas,int count)
{
	int i,min = 0;
	min = mas[0];
	for(i = 1; i < count; i++)
	{
		if(mas[i] < min)
		{
			min = mas[i];
		}
	}
	return min;
}
/*Функция адресации. 1-й параметр - определение отношения: 1 - часть, 0 - сдвиг
					 2-й параметр - определение длины сдвига */				 
void
addressing_function(struct sdvig* sdvig_struct,int ch,int rast,char * stor)
{	
    opredelenie_storony(sdvig_struct,stor);
	sdvig_struct->chastichnost = ch;
    sdvig_struct->rasstoyanie = rast;
}
void 
add(struct go **h, char* init_go_landshaft, char** init_go_nazvanie, int init_shirina, int init_vysota, int init_base_point_x, int init_base_point_y, int *init_prot_x,int *init_prot_y,int init_count_of_zones,char /*****/ init_zones_names [5][10][20])
{ 
	int i,j;
    struct go *n;
    struct go *t;
    if(!(n=(struct go *)calloc(1,sizeof(struct go))))
    { 
        return;
    }
    /*инициализация новой структуры*/
    strcpy(n->go_landshaft,init_go_landshaft);
    for(i = 0; strcmp(init_go_nazvanie[i],""); i++)
    {
		strcpy(n->go_nazvanie[i],init_go_nazvanie[i]);
	}		
    n->shirina = init_shirina;
    n->vysota = init_vysota;
    n->base_point_x = init_base_point_x;
    n->base_point_y = init_base_point_y; 
    n->count_of_zones = init_count_of_zones; 
    for(i = 0; i < 5; i++)
    {
	   for(j = 0; j < 10; j++)
	   {
			strcpy(n->zone_names[i][j],"");
	   }
    } 
    for(i = 0; i < init_count_of_zones; i++)
    {
		for(j = 0; strcmp(init_zones_names[i][j],""); j++)
		{
			strcpy(n->zone_names[i][j],init_zones_names[i][j]);
		}	
    }
    for(i = 0; i <= last; i++)
    {
		n->prot_point_x[i] = init_prot_x[i]; 
		n->prot_point_y[i] = init_prot_y[i];
    }  
    n->index_last = last;
    calculate_keypoints(init_shirina,init_vysota,init_base_point_x,init_base_point_y,n->key_points_x,n->key_points_y);  
    if (!*h) 
    { 
	    *h=n; 
	}
    else
    { 
		t = *h;
		while(t->nx)
		{
			t = t->nx;
		}
		t->nx = n;
    }
}
struct go*
element(struct go **h,int index)
{
	int i=0;
	struct go *n;
    n = *h;
	while(n)
	{
		if(i==index)
		{
			return n;
		}
		n = n->nx;
		i++;
	}
	return NULL;
}
void
opredelenie_storony(struct sdvig* sdvig_struct,char * tec_storona)
{
	if(!strcmp(tec_storona,"северо-западная")||!strcmp(tec_storona,"северо-запад")||!strcmp(tec_storona,"северо-западнее"))
		sdvig_struct->storona = 1;
	if(!strcmp(tec_storona,"северная")||!strcmp(tec_storona,"север")||!strcmp(tec_storona,"севернее"))
		sdvig_struct->storona = 2;
	if(!strcmp(tec_storona,"северо-восточная")||!strcmp(tec_storona,"северо-восток")||!strcmp(tec_storona,"северо-восточнее"))
		sdvig_struct->storona = 3;
	if(!strcmp(tec_storona,"западная")||!strcmp(tec_storona,"запад")||!strcmp(tec_storona,"западнее"))
		sdvig_struct->storona = 4;
	if(!strcmp(tec_storona,"центральная"))
		sdvig_struct->storona = 5;
	if(!strcmp(tec_storona,"восточная")||!strcmp(tec_storona,"восток")||!strcmp(tec_storona,"восточнее"))
		sdvig_struct->storona = 6;
	if(!strcmp(tec_storona,"юго-западная")||!strcmp(tec_storona,"юго-запад")||!strcmp(tec_storona,"юго-западнее"))
		sdvig_struct->storona = 7;
	if(!strcmp(tec_storona,"южная")||!strcmp(tec_storona,"юг")||!strcmp(tec_storona,"южнее"))
		sdvig_struct->storona = 8;
	if(!strcmp(tec_storona,"юго-восточная")||!strcmp(tec_storona,"юго-восток")||!strcmp(tec_storona,"юго-восточнее"))
		sdvig_struct->storona = 9;
}
void
calculate_keypoints(int shirina, int vysota, int base_x, int base_y, int* points_x,int* points_y)
{
    base_x = base_x - shirina/2; // стали в "ноль"
    base_y = base_y - vysota/2;
    
	points_x[0] = base_x;			 points_y[0] = base_y;
	points_x[1] = base_x+shirina/3;	 points_y[1] = base_y;
	points_x[2] = base_x+shirina*2/3;points_y[2] = base_y;
	points_x[3] = base_x+shirina;	 points_y[3] = base_y;
	
	points_x[4] = base_x;			 points_y[4] = base_y+vysota/3;
	points_x[5] = base_x+shirina/3;  points_y[5] = base_y+vysota/3;
	points_x[6] = base_x+shirina*2/3;points_y[6] = base_y+vysota/3;
	points_x[7] = base_x+shirina;	 points_y[7] = base_y+vysota/3;
	
	points_x[8] = base_x;			  points_y[8] = base_y+vysota*2/3;
	points_x[9] = base_x+shirina/3;   points_y[9] = base_y+vysota*2/3;
	points_x[10] = base_x+shirina*2/3;points_y[10] = base_y+vysota*2/3;
	points_x[11] = base_x+shirina;    points_y[11] = base_y+vysota*2/3;
	
	points_x[12] = base_x;			  points_y[12] = base_y+vysota;
	points_x[13] = base_x+shirina/3;  points_y[13] = base_y+vysota;
	points_x[14] = base_x+shirina*2/3;points_y[14] = base_y+vysota;
	points_x[15] = base_x+shirina;    points_y[15] = base_y+vysota;
}
int 
main(void)
{     
   yyparse();
}
